package cn.itcast.n4_共享模型_管程;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

import static cn.itcast.util.Sleeper.sleep;

/**
 * @program: juc
 * @description:
 * @author: flyduck
 * @create: 2024-10-10 14:01
 **/
@Slf4j(topic = "c.Test32_$$$$$_wait_notify设计模式_生产者消费者模式")
public class Test32_$$$$$_wait_notify设计模式_生产者消费者模式 {
    public static void main(String[] args) {
        MessageQueue messageQueue = new MessageQueue(2);
        for (int i = 0; i < 3; i++) {
            int id = i;
            new Thread(() -> {
                messageQueue.putMessage(new Message(id, "值" + id));
            },"生产者" + i).start();
        }

        new Thread(() -> {
            while (true) {
                sleep(1);
                messageQueue.getMessage();
            }
        },"消费者").start();
    }
}

//消息队列类
@Slf4j(topic = "c.MessageQueue")
class MessageQueue{

    private int capacity;//容量
    private LinkedList<Message> messageList = new LinkedList<>();//存储消息的容器

    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    //获取消息
    public Message getMessage(){
        synchronized (messageList) {
            while (messageList.isEmpty()) {
                try {
                    log.debug("队列为空，消费者线程等待");
                    messageList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Message message = messageList.removeFirst();
            log.debug("已消费消息:{}", message);
            messageList.notifyAll();
            return message;
        }


    }

    //存储消息
    public void putMessage(Message message){
        synchronized (messageList) {
            while (messageList.size() == capacity) {
                try {
                    log.debug("队列为满，生产者线程等待");
                    messageList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            messageList.addLast(message);
            log.debug("已生产消息:{}", message);
            messageList.notifyAll();
        }
    }
}

@Getter
@AllArgsConstructor
@ToString
final class Message{
    private int id;
    private Object value;
}
